
import { BaseService } from '@/base/base.service';
import { pageData } from '@/util/util';
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { wxUser } from '@prisma/client';
import { LoginWxUserDto } from './dto/login-wxuser.dto';
import { RecudePhoneCountDto } from './dto/recude-phone-count-dto';
import { UpdateWxUserDto } from './dto/update-wxuser.dto';
const dayjs = require('dayjs')
const customParseFormat = require('dayjs/plugin/customParseFormat')
const isBetween = require('dayjs/plugin/isBetween')
dayjs.extend(isBetween)
dayjs.extend(customParseFormat)

@Injectable()
export class WxuserService {

  constructor(private baseService: BaseService, private jwt: JwtService) {}

  async wxUserLogin(dto: LoginWxUserDto) {
    const wxuser = await this.baseService.wxUser.findUnique({
      where: {
        phone: dto.phone
      }
    })
    if(!wxuser) {
      const regUser = await this.baseService.wxUser.create({
        data: {
          ...dto
        }
      })
      return this.token(regUser)
    }
    return this.token(wxuser)
  }

  async updateWxUser(id: string, dto: UpdateWxUserDto) {
    const wxuser = this.baseService.wxUser.update({
      where: {
        id
      },
      data: {
       ...dto
      }
    })
    return wxuser
  }

  private async token(user: wxUser) {
    const { phone, id } = user
    return {
      user,
      token: await this.jwt.signAsync({
        phone,
        sub: id
      })
    }
  }

  async findPage(query: any) {
    return await pageData<wxUser>('wxUser', query)
  }

  async addVip(id: string, dayDto: { id: string, day: number, discount: number, bonusCoins: number }) {
    const user = await this.baseService.wxUser.findUnique({
      where: {
        id
      }
    })
    let updateUser = user
    if(updateUser.isVip) {
      let end = dayjs(updateUser.vipEnd, 'YYYY-MM-DD').add(dayDto.day, 'day').format('YYYY-MM-DD')
      updateUser.vipId = id
      updateUser.userDiscount = dayDto.discount
      updateUser.coin = updateUser.coin + dayDto.bonusCoins
      updateUser.vipEnd = String(end)
    } else {
      updateUser.isVip = true
      updateUser.vipId = id
      updateUser.userDiscount = dayDto.discount
      updateUser.coin = updateUser.coin + dayDto.bonusCoins
      let start = dayjs().format('YYYY-MM-DD').toString()
      let end = dayjs(start, 'YYYY-MM-DD').add(dayDto.day, 'day').format('YYYY-MM-DD')
      updateUser.vipStart = String(start)
      updateUser.vipEnd = String(end)
    }
    const lastUser = this.baseService.wxUser.update({
      where: {
        id: updateUser.id
      },
      data: updateUser
      
    })
    return lastUser
  }

  
  async addCoin(id: string, coinDto: { coin: number }) {
    const user = await this.baseService.wxUser.findUnique({
      where: {
        id
      }
    })
    // user.getPhoneCount = user.getPhoneCount + countDto.count
    user.coin = user.coin + coinDto.coin
    const updateUser = this.baseService.wxUser.update({
      where: {
        id: user.id
      },
      data: user
    })
    return updateUser
  }

  /**
   * 减少次数
   */
  async reducePhoneCountByChannel(dto: RecudePhoneCountDto) {
    const user = await this.baseService.wxUser.findUnique({
      where: {
        id: dto.userId
      }
    })
    const personalChannel = await this.baseService.personalChannel.findUnique({
      where: {
        id: dto.id
      }
    })
    await this.baseService.personalChannel.update({
      where: {
        id: dto.id
      },
      data: {
        buyCount: personalChannel.buyCount + 1
      }
    })
    await this.baseService.myChannel.create({
      data: {
        channelName: personalChannel.personalCarName,
        brand: personalChannel.brand,
        mileage: personalChannel.mileage,
        registrationDate: personalChannel.registrationDate,
        homeLocation: personalChannel.homeLocation,
        channelId: personalChannel.id,
        userId: dto.userId
      }
    })
    const updateUser = await this.baseService.wxUser.update({
      where: {
        id: user.id
      },
      data: {
        coin: user.coin - dto.reduceCoin
      }
    })
    
    return updateUser
  }

  async reducePhoneCountByClue(dto: RecudePhoneCountDto) {
    const user = await this.baseService.wxUser.findUnique({
      where: {
        id: dto.userId
      }
    })
    const newCarClue = await this.baseService.newCarClue.findUnique({
      where: {
        id: dto.id
      }
    })
    await this.baseService.newCarClue.update({
      where: {
        id: newCarClue.id
      },
      data: {
        buyCount: newCarClue.buyCount + 1
      }
    })
    await this.baseService.myClue.create({
      data: {
       clueName: newCarClue.clueName,
       brand: newCarClue.brand,
       location: newCarClue.location,
       clueId: newCarClue.id,
       userId: dto.userId
      }
    })
    const updateUser = await this.baseService.wxUser.update({
      where: {
        id: user.id
      },
      data: {
        coin: user.coin - dto.reduceCoin
      }
    })
    
    return updateUser
  }

  async reducePhoneCountByPeer(dto: RecudePhoneCountDto){
    const user = await this.baseService.wxUser.findUnique({
      where: {
        id: dto.userId
      }
    })
    const peerCar = await this.baseService.peerCar.findUnique({
      where: {
        id: dto.id
      }
    })
    await this.baseService.peerCar.update({
      where: {
        id: dto.id
      },
      data: {
        buyCount: peerCar.buyCount + 1
      }
    })
    await this.baseService.myPeer.create({
      data: {
        carName: peerCar.carName,
        brand: peerCar.brand,
        mileage: peerCar.mileage,
        registrationDate: peerCar.registrationDate,
        homeLocation: peerCar.homeLocation,
        peerId: peerCar.id,
        userId: dto.userId
      }
    })
    const updateUser = await this.baseService.wxUser.update({
      where: {
        id: user.id
      },
      data: {
        coin: user.coin - dto.reduceCoin
      }
    })
    
    return updateUser
  }

  async checkHaveChannel(id: string, userId: string) {
    const myChannel = await this.baseService.myChannel.findFirst({
      where: {
        userId: userId,
        channelId: id
      }
    })
    if(!myChannel) {
      return false
    }
    return true
  }

  async checkHaveClue(id: string, userId: string) {
    const myClue = await this.baseService.myClue.findFirst({
      where: {
        userId: userId,
        clueId: id
      }
    })
    if(!myClue) {
      return false
    }
    return true
  }

  async checkHavePeer(id: string, userId: string) {
    const myPeer = await this.baseService.myPeer.findFirst({
      where: {
        userId: userId,
        peerId: id
      }
    })
    if(!myPeer) {
      return false
    }
    return true
  }

  async getMyChannel(id: string) {
    return await this.baseService.myChannel.findMany({
      where: {
        userId: id
      }
    })
  }

  async getMyClue(id: string) {
    return await this.baseService.myClue.findMany({
      where: {
        userId: id
      }
    })
  }
  
  async getMyPeer(id: string) {
    return await this.baseService.myPeer.findMany({
      where: {
        userId: id
      }
    })
  }

  async checkWxUserExpire(id: string) {
    const wxUser = await this.baseService.wxUser.findUnique({
      where: {
        id
      }
    })
    //检查是否vip
    if(wxUser.isVip) {
      const res = dayjs().isBetween(dayjs(wxUser.vipStart, 'YYYY-MM-DD'), dayjs(wxUser.vipEnd, 'YYYY-MM-DD'))
      if(!res) {
        await this.baseService.wxUser.update({
          where: {
            id
          },
          data: {
            isVip: false,
            vipStart: null,
            vipEnd: null,
            vipId: null
          }
        })
        return true
      } else {
        return false
      }
    } else {
      return false
    }
  }

  async getUserDetail(id: string) {
    return await this.baseService.wxUser.findUnique({
      where: {
        id
      }
    })
  }
}

